home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / include / asm / tlbflush.h < prev    next >
C/C++ Source or Header  |  2005-10-13  |  4KB  |  148 lines

  1. #ifndef _I386_TLBFLUSH_H
  2. #define _I386_TLBFLUSH_H
  3.  
  4. #include <linux/config.h>
  5. #include <linux/mm.h>
  6. #include <asm/processor.h>
  7.  
  8. #define __flush_tlb()                            \
  9.     do {                                \
  10.         unsigned int tmpreg;                    \
  11.                                     \
  12.         __asm__ __volatile__(                    \
  13.             "movl %%cr3, %0;              \n"        \
  14.             "movl %0, %%cr3;  # flush TLB \n"        \
  15.             : "=r" (tmpreg)                    \
  16.             :: "memory");                    \
  17.     } while (0)
  18.  
  19. /*
  20.  * Global pages have to be flushed a bit differently. Not a real
  21.  * performance problem because this does not happen often.
  22.  */
  23. #define __flush_tlb_global()                        \
  24.     do {                                \
  25.         unsigned int tmpreg;                    \
  26.                                     \
  27.         __asm__ __volatile__(                    \
  28.             "movl %1, %%cr4;  # turn off PGE     \n"    \
  29.             "movl %%cr3, %0;                     \n"    \
  30.             "movl %0, %%cr3;  # flush TLB        \n"    \
  31.             "movl %2, %%cr4;  # turn PGE back on \n"    \
  32.             : "=&r" (tmpreg)                \
  33.             : "r" (mmu_cr4_features & ~X86_CR4_PGE),    \
  34.               "r" (mmu_cr4_features)            \
  35.             : "memory");                    \
  36.     } while (0)
  37.  
  38. extern unsigned long pgkern_mask;
  39.  
  40. # define __flush_tlb_all()                        \
  41.     do {                                \
  42.         if (cpu_has_pge)                    \
  43.             __flush_tlb_global();                \
  44.         else                            \
  45.             __flush_tlb();                    \
  46.     } while (0)
  47.  
  48. #define cpu_has_invlpg    (boot_cpu_data.x86 > 3)
  49.  
  50. #define __flush_tlb_single(addr) \
  51.     __asm__ __volatile__("invlpg %0": :"m" (*(char *) addr))
  52.  
  53. #ifdef CONFIG_X86_INVLPG
  54. # define __flush_tlb_one(addr) __flush_tlb_single(addr)
  55. #else
  56. # define __flush_tlb_one(addr)                        \
  57.     do {                                \
  58.         if (cpu_has_invlpg)                    \
  59.             __flush_tlb_single(addr);            \
  60.         else                            \
  61.             __flush_tlb();                    \
  62.     } while (0)
  63. #endif
  64.  
  65. /*
  66.  * TLB flushing:
  67.  *
  68.  *  - flush_tlb() flushes the current mm struct TLBs
  69.  *  - flush_tlb_all() flushes all processes TLBs
  70.  *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
  71.  *  - flush_tlb_page(vma, vmaddr) flushes one page
  72.  *  - flush_tlb_range(vma, start, end) flushes a range of pages
  73.  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
  74.  *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  75.  *
  76.  * ..but the i386 has somewhat limited tlb flushing capabilities,
  77.  * and page-granular flushes are available only on i486 and up.
  78.  */
  79.  
  80. #ifndef CONFIG_SMP
  81.  
  82. #define flush_tlb() __flush_tlb()
  83. #define flush_tlb_all() __flush_tlb_all()
  84. #define local_flush_tlb() __flush_tlb()
  85.  
  86. static inline void flush_tlb_mm(struct mm_struct *mm)
  87. {
  88.     if (mm == current->active_mm)
  89.         __flush_tlb();
  90. }
  91.  
  92. static inline void flush_tlb_page(struct vm_area_struct *vma,
  93.     unsigned long addr)
  94. {
  95.     if (vma->vm_mm == current->active_mm)
  96.         __flush_tlb_one(addr);
  97. }
  98.  
  99. static inline void flush_tlb_range(struct vm_area_struct *vma,
  100.     unsigned long start, unsigned long end)
  101. {
  102.     if (vma->vm_mm == current->active_mm)
  103.         __flush_tlb();
  104. }
  105.  
  106. #else
  107.  
  108. #include <asm/smp.h>
  109.  
  110. #define local_flush_tlb() \
  111.     __flush_tlb()
  112.  
  113. extern void flush_tlb_all(void);
  114. extern void flush_tlb_current_task(void);
  115. extern void flush_tlb_mm(struct mm_struct *);
  116. extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
  117.  
  118. #define flush_tlb()    flush_tlb_current_task()
  119.  
  120. static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long start, unsigned long end)
  121. {
  122.     flush_tlb_mm(vma->vm_mm);
  123. }
  124.  
  125. #define TLBSTATE_OK    1
  126. #define TLBSTATE_LAZY    2
  127.  
  128. struct tlb_state
  129. {
  130.     struct mm_struct *active_mm;
  131.     int state;
  132.     char __cacheline_padding[L1_CACHE_BYTES-8];
  133. };
  134. DECLARE_PER_CPU(struct tlb_state, cpu_tlbstate);
  135.  
  136.  
  137. #endif
  138.  
  139. #define flush_tlb_kernel_range(start, end) flush_tlb_all()
  140.  
  141. static inline void flush_tlb_pgtables(struct mm_struct *mm,
  142.                       unsigned long start, unsigned long end)
  143. {
  144.     /* i386 does not keep any page table caches in TLB */
  145. }
  146.  
  147. #endif /* _I386_TLBFLUSH_H */
  148.